package cn.yilongquan.service.impl;

import cn.yilongquan.mapper.ArticleMapper;
import cn.yilongquan.mapper.IpAddressMapper;
import cn.yilongquan.service.ArticleService;
import cn.yilongquan.system.domain.IpAddress;
import cn.yilongquan.user.domain.Article;
import cn.yilongquan.user.domain.BlogArticle;
import cn.yilongquan.user.query.ArticleQuery;
import cn.yilongquan.util.R;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class ArticleServiceImpl implements ArticleService {


    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private IpAddressMapper ipAddressMapper; // 新增的IP记录Mapper

    @Override
    public Article findById(Long id) {
        return articleMapper.findById(id);
    }

    @Override
    public List<Article> findAll() {
        return articleMapper.findAll();
    }

    @Override
    public void add(Article article) {
        article.setCreateTime(new Date());
        article.setArticleReadCount(0);
        article.setArticleStarNum(0);
        article.setArticleCommentNum(0);
        articleMapper.add(article);
        //同步到mongodb里面
        BlogArticle blogArticle = new BlogArticle();
        //类的复制，字段和类型必须一致
        BeanUtils.copyProperties(article, blogArticle);

        mongoTemplate.save(blogArticle);
    }

    @Override
    public void update(Article article) {
        article.setUpdateTime(new Date());
        articleMapper.update(article);
        Query query = Query.query( Criteria.where("id").is(article.getId()));
        BlogArticle one = mongoTemplate.findOne(query, BlogArticle.class);
        mongoTemplate.save(one);

    }

    @Override
    public void deleteById(Long id) {
        articleMapper.deleteById(id);

        Query query = Query.query( Criteria.where("id").is(id));
        mongoTemplate.remove(query);

    }

    @Override
    public void batchDelete(List<Long> ids) {
        articleMapper.batchDelete(ids);
    }

    @Override
    public R pageList(ArticleQuery articleQuery) {
        // 1. 先查询 MySQL（因为内容存在 MySQL，优先保证数据完整）
        PageHelper.startPage(articleQuery.getPage(), articleQuery.getSize());
        List<Article> mysqlArticles = articleMapper.pageList(articleQuery);
        PageInfo<Article> mysqlPageInfo = new PageInfo<>(mysqlArticles);

        // 2. 如果 MySQL 无数据，再查询 MongoDB（可选，根据业务决定是否需要）
        if (CollectionUtils.isEmpty(mysqlArticles)) {
            Criteria criteria = Criteria.where("id").exists(true);
            Query query = Query.query(criteria);
            query.skip((articleQuery.getPage() - 1) * articleQuery.getSize())
                    .limit(articleQuery.getSize());

            List<BlogArticle> mongoArticles = mongoTemplate.find(query, BlogArticle.class);
            if (!CollectionUtils.isEmpty(mongoArticles)) {
                PageInfo<BlogArticle> mongoPageInfo = new PageInfo<>();
                mongoPageInfo.setList(mongoArticles);
                mongoPageInfo.setPageNum(articleQuery.getPage());
                mongoPageInfo.setPageSize(articleQuery.getSize());
                mongoPageInfo.setTotal(mongoTemplate.count(query, BlogArticle.class));
                return R.ok(mongoPageInfo);
            }
        }

        // 3. MySQL 有数据，直接返回完整内容（包含 articleContent）
        return R.ok(mysqlPageInfo);
    }

    // 实现查询同类型相关文章
    @Override
    public List<Article> findRelatedByType(Long articleType, Long currentId) {
        System.out.println("进入 findRelatedByType，参数：articleType=" + articleType + " currentId=" + currentId);
        List<Article> result = articleMapper.findRelatedByType(articleType, currentId);
        System.out.println("查询到相关文章数量：" + result.size());
        return result;
    }

    @Override
    public void DatatoMongoDB() {
        List<Article> all = articleMapper.findAll();
        List<BlogArticle> collect = all.stream().map(article -> {
            BlogArticle blogArticle = new BlogArticle();
            BeanUtils.copyProperties(article, blogArticle);
            return blogArticle;
        }).collect(Collectors.toList());

        mongoTemplate.dropCollection("article");
        mongoTemplate.save(collect);
    }

    // 新增：实现获取点赞数前六的文章
    @Override
    public List<Article> findTop6ByStarNum() {
        // 调用Mapper层方法查询数据库
        List<Article> topArticles = articleMapper.findTop6ByStarNum();

        // 可选：日志打印，方便调试
        if (topArticles != null) {
            System.out.println("查询到点赞数前六的文章数量：" + topArticles.size());
        }

        return topArticles;
    }

    @Override
    public List<Map<String, Object>> findTop5TagCount() {
        return articleMapper.findTop5TagCount();
    }

    @Override
    public int increaseReadCount(Long id) {
        // 执行+1操作
        articleMapper.increaseReadCount(id);
        // 返回更新后的浏览量
        return articleMapper.getReadCountById(id);
    }

    @Override
    public boolean starArticle(Long articleId, String userIp) {
        // 1. 检查该IP是否已对该文章点赞
        boolean hasLiked = ipAddressMapper.existsByArticleIdAndIp(articleId, userIp);

        if (hasLiked) {
            return false; // 已点赞，返回失败
        }
        // 2. 未点赞：更新文章点赞数（+1）
        int updateCount = articleMapper.increaseStarNum(articleId);
        if (updateCount <= 0) {
            throw new RuntimeException("更新点赞数失败");
        }
        // 3. 记录IP点赞记录
        IpAddress ipRecord = new IpAddress();
        ipRecord.setArticleId(articleId);
        ipRecord.setAddress(userIp);
        ipRecord.setCreateTime(new Date());
        ipAddressMapper.insert(ipRecord);
        return true; // 点赞成功
    }

    /**
     * 获取文章当前点赞数
     * @param articleId 文章ID
     * @return 点赞数
     */
    @Override
    public int getStarNum(Long articleId) {
        Article article = articleMapper.findById(articleId);
        return article != null ? article.getArticleStarNum() : 0;
    }

    @Override
    public int unstarArticle(Long articleId, String userIp) {
        // 步骤1：删除该用户IP对该文章的点赞记录
        ipAddressMapper.deleteByArticleIdAndIp(articleId, userIp);

        // 步骤2：更新文章点赞数（减1，最小为0）
        Article article = articleMapper.findById(articleId);
        if (article == null) {
            throw new RuntimeException("文章不存在");
        }
        int newStarNum = Math.max(0, article.getArticleStarNum() - 1);
        article.setArticleStarNum(newStarNum);
        articleMapper.update(article); // 调用已有的更新方法

        return newStarNum; // 返回更新后的点赞数
    }


}